package com.cdks.wuxiu.api.util;

import cn.hutool.json.JSONUtil;

import com.cdks.wuxiu.common.config.WxpayProps;
import com.cdks.wuxiu.common.exception.ApiException;
import com.cdks.wuxiu.common.util.ServletUtils;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.UnifiedOrderModel;

import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.Map;

@Slf4j
public class WxpayUtils {
    /**
     * 应用ID
     */
    private static final String APP_ID = WxpayProps.appId;
    /**
     * 应用对应的密钥
     */
    private static final String APP_SECRET = WxpayProps.appSecret;
    /**
     * 微信支付商户号
     */
    private static final String MCH_ID = WxpayProps.mchId;
    /**
     * 证书路径
     */
    private static final String CERT_PATH = WxpayProps.certPath;
    /**
     * 支付通知域名
     */
    private static final String DOMAIN = WxpayProps.domain;
    /**
     * 异步回调地址 店铺续费
     */
    public static final String NOTIFY_URL = "api/payment/wxpay";

    
    static {
        WxPayApiConfig wxPayApiConfig = getApiConfig();
        WxPayApiConfigKit.putApiConfig(wxPayApiConfig);
        log.info("微信支付参数初始化成功:" + JSONUtil.toJsonStr(wxPayApiConfig));
    }

    /**
     * 初始化微信支付参数配置
     */
    public static WxPayApiConfig getApiConfig() {
        return WxPayApiConfig.builder()
                .appId(APP_ID)
                .mchId(MCH_ID)
                .partnerKey(APP_SECRET)
                .certPath(CERT_PATH)
                .domain(DOMAIN)
                .build();
    }

    /**
     * 生成 APP 支付订单
     *
     * @param orderNo  订单编号
     * @param totalFee 总金额
     * @param subject  订单标题
     * @param type     回调类型
     * @return 签名参数 直接返回给客户端
     */
    public static Map<String, String> appPay(String orderNo, BigDecimal totalFee, String subject) {
        Map<String, String> params = UnifiedOrderModel.builder()
                .appid(APP_ID)
                .mch_id(MCH_ID)
                .nonce_str(WxPayKit.generateStr())
                .body(subject)
                .out_trade_no(orderNo)
                .total_fee(yuanToFen(totalFee))
                .spbill_create_ip(ServletUtils.getIpAddress())
                .notify_url(DOMAIN + NOTIFY_URL)
                .trade_type(TradeType.APP.getTradeType())
                .build()
                .createSign(APP_SECRET, SignType.MD5);

        log.info("微信创建APP支付订单 params:" + params);
        String xmlResult = WxPayApi.pushOrder(false, params);
        Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
        log.info("微信创建APP支付订单 result:" + result);
        String returnCode = result.get("return_code");
        String returnMsg = result.get("return_msg");
        if (!WxPayKit.codeIsOk(returnCode)) {
            throw new ApiException(-20, returnMsg);
        }
        
        String resultCode = result.get("result_code");
        if (!WxPayKit.codeIsOk(resultCode)) {
            throw new ApiException(-20, returnMsg);
        }
        // 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
        String prepayId = result.get("prepay_id");
        return WxPayKit.appPrepayIdCreateSign(APP_ID, MCH_ID, prepayId, APP_SECRET, SignType.MD5);
    }

    /**
     * 金额 BigDecimal 元转分 String 无小数位
     */
    public static String yuanToFen(BigDecimal yuan) {
        return yuan.multiply(BigDecimal.valueOf(100)).stripTrailingZeros().toPlainString();
    }
}
